package com.ideal.hadoopadmin.crontab.kerberos;


import com.ideal.hadoopadmin.crontab.db.ConnectionManager;
import com.ideal.hadoopadmin.crontab.property.Properties;
import com.ideal.hadoopadmin.crontab.tool.Tools;
import com.ideal.tools.ssh.common.CommonProperties;
import com.ideal.tools.ssh.common.OperationMarket;
import com.ideal.tools.ssh.context.ClusterContext;
import com.ideal.tools.ssh.entity.LinuxMachine;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by CC on 2016/3/16.
 * 这个主要是为了 运行kerberos 的日常更新
 */
public class KerberosCrontab {


    public static  String kerberosFileName;
    public static String kerberosExeShell;

    public static void RefreshKerberosDaily(){
        String dayJobPath= Properties.instance().getPropertyByKey(CommonProperties.WEBAPP_DAILY_JOB_PATH,"");
        kerberosFileName= dayJobPath+Tools.getKerberosInfoFileName();
        kerberosExeShell= dayJobPath + Tools.getKerberosExeShellName();
        //获取 信息
        List<Map<String,Object>> configList = readKDCConfigInfo();

        //刷新kdc
        authKDC();

        //删除原始数据库
        deleteKDCAuthInfo();

        //插入原始数据



    }

    public static void authKDC(){
        List<Map<String,Object>> configList = readKDCConfigInfo();
        //webapp 机器
        List<LinuxMachine> webAPP = getMachineByType("9");

        String path = Properties.instance().getPropertyByKey(CommonProperties.WEBAPP_SHELL_PATH,"");
        String realm = Properties.instance().getPropertyByKey(CommonProperties.KDC_PRINC_REALM, "@EXAMPLE.COM");

//        String shellPath =

        StringBuffer sb = new StringBuffer();
        sb.append("#!/bin/bash"+Properties.Linux_Delimited);
        for(Map<String,Object> user:configList){
            String userName = user.get("USERNAME").toString();
            String sysPW = user.get("SYSTEMPW").toString();
            String ids = user.get("MACHINEIDS").toString();

            List<LinuxMachine> machines = getAuthMachine(ids);

            String kdc_princi=userName+ realm;
            for(LinuxMachine host:machines){
                String machineID=host.getSshAuthor().getHost().split(",")[1];
                host.initIP(host.getSshAuthor().getHost().split(",")[0]);
                String param=host.getSshAuthor().getHost()+" "+host.getSshAuthor().getUsername()
                        +" '"+host.getSshAuthor().getPasswd()+
                        "' "+userName+" "+kdc_princi + " '" + sysPW+"'";
                String cmd="echo -e \"\\n"+ Properties.Kerberos_Start+":"+host.getSshAuthor().getHost()
                        +","+userName+","+kdc_princi+","+machineID+":param_end\">>"+kerberosFileName+";" +
                        "expect "+path+"/authClientPrinc.exp "+param+">>"+kerberosFileName+";" +
                        "echo -e \"\\n"+Properties.Kerberos_End+"\\n\">>"+kerberosFileName;
                //加上分隔符
                cmd=cmd+Properties.Linux_Delimited;

                sb.append(cmd);
            }

        }
        //生成文件
        Tools.writeLinuxFile(kerberosExeShell,sb);

        //执行
        CommonProperties commonProperties=new CommonProperties(new HashMap<String, String>());
        ClusterContext clusterContext =new ClusterContext(commonProperties);
        for(LinuxMachine linuxMachine:webAPP){
            linuxMachine.initOperation(OperationMarket.ExeOneShellCMD("sh "+kerberosExeShell));
        }
        clusterContext.setMachineList(webAPP);
        clusterContext.doTheThing();
        clusterContext.printResult();

    }


    /**
     * 获取kdc 的配置信息
     * @return
     */
    public static List<Map<String,Object>> readKDCConfigInfo(){
        String sql="select cluster_user.userName,cluster_user.systemPW,cluster_user_kbrconfig.machineIds " +
                "from cluster_user_kbrconfig left join cluster_user " +
                "on cluster_user_kbrconfig.userId = cluster_user.id " +
                "where cluster_user_kbrconfig.status =1";
        Connection conn= ConnectionManager.getConnection();

        List<Map<String,Object>> rsList=ConnectionManager.queryDB(conn, sql);

        return rsList;
    }

    public static void deleteKDCAuthInfo(){
        String sql = "delete from cluster_user_kbrauth ";
        ConnectionManager.exeSQL(sql);
    }

    /**
     * 机器
     * @return
     */
    public static List<Map<String,Object>> getMachines(){
        String sql = "select * from "+Properties.MACHINE_TABLE;
        Connection conn= ConnectionManager.getConnection();

        List<Map<String,Object>> rsList=ConnectionManager.queryDB(conn, sql);

        return rsList;
    }

    public static LinuxMachine getMachineByID(List<Map<String,Object>> machines,String id){
        for(Map<String,Object> map : machines){

            String machineid =  map.get("ID").toString();
            String machineType = map.get("MACHINETYPEID").toString();
            String ip=  map.get("MACHINEIP").toString();
            String user = map.get("LOGINUSERNAME").toString();
            String pw = map.get("LOGINPASSWORD").toString();
            if(machineid.equals(id)){
                return new LinuxMachine().initIP(ip+","+id).initLoginName(user)
                        .initPassWord(pw);
            }
        }
        return null;
    }


    public static List<LinuxMachine> getMachineByType(String typeID){
        List<Map<String,Object>> machines= getMachines();
        List<LinuxMachine> machineList= new ArrayList<LinuxMachine>();
        for(Map<String,Object> map : machines){
            String machineType = map.get("MACHINETYPEID").toString();
            String ip=  map.get("MACHINEIP").toString();
            String user = map.get("LOGINUSERNAME").toString();
            String pw = map.get("LOGINPASSWORD").toString();
            LinuxMachine machine = new LinuxMachine().initIP(ip).initLoginName(user)
                    .initPassWord(pw);
            if(typeID ==null){
                machineList.add(machine);
            }else if(typeID.equals(machineType)){
                machineList.add(machine);
            }
        }
        return machineList;
    }


    public static List<LinuxMachine> getAuthMachine(String ids){
        String[] ips = ids.split(",");
        List<Map<String,Object>> allMachine = getMachines();
        List<LinuxMachine> machines = new ArrayList<LinuxMachine>();

        for(String ip: ips){
            machines.add(getMachineByID(allMachine,ip));
        }
        return machines;
    }

    public static Map<String,String> getUserInfo(){
        String sql="select username,id from cluster_user";
        Connection conn= ConnectionManager.getConnection();
        List<Map<String,Object>> list =ConnectionManager.queryDB(conn,sql);
        Map<String,String> finalMap = new HashMap<String, String>();
        for(Map<String,Object> item:list){
            String username =item.get("USERNAME").toString();
            String passwd = item.get("ID").toString() ;
            finalMap.put(username,passwd);
        }
        return finalMap;
    }


    /**
     * 解析 日志文件
     * @return
     */
    public List<String> parseKerberosInfo(){
        List<String> sqlList=new ArrayList<String>();

        Map<String,String> userInfo=getUserInfo();
        //读取日志文件类容
        List<String> kerberosList=Tools.readFile2List(kerberosFileName);
        String sql="";
        boolean started=false;
        String params="";
        String path="";
        String start="";
        String end="";
        String status="0";
        String user="";
        boolean time=false;
        for(String info:kerberosList){
            if(info.startsWith(Properties.Kerberos_Start)){
                started=true;
                params=info.split(":")[1];
                String mc_ip=params.split(",")[0];
                user=params.split(",")[1];
                String userid=userInfo.get(user);
                if(userid==null)
                    userid=user;
                String ker_princ=params.split(",")[2];
                sql="insert into kdc_auth (mc_ip,hp_user_id,ker_start_time,ker_end_time,ker_princ,ticket_cahce_path,ker_status)" +
                        "values('"+mc_ip+"','"+userid+"','@start@','@end@','"+ker_princ+"','@path@',@status@)";
            }else if(info.startsWith(Properties.Kerberos_End)){
                if(start.trim().length()==0||end.trim().length()==0)
                    status="1";
                started=false;
                //还需要分析是否有没有替换完成的参数
                sql=sql.replace("@start@",start);
                sql=sql.replace("@end@",end);
                sql=sql.replace("@path@",path);
                sql=sql.replace("@status@",status);
                sqlList.add(sql);
                //清空参数
                sql="";path="";start="";end="";status="0";time=false;
            }
            if(started){
                //替换参数
                //status 0成功 1失败
                if(info.contains("Password incorrect")){
                    status="1";
                }
                //path
                if(info.contains("Ticket cache:")){
                    String[] tmp=info.split(":");
                    if(tmp.length>=3)path=tmp[2].trim();
                }
                //start end
                if(info.contains("Valid starting")){
                    time=true;
                }
                if(time&&!info.contains("Valid starting")){
                    String[] tmp=info.split(" ");
                    if(tmp.length>=5){
                        start=tmp[0]+" "+tmp[1];
                        end=tmp[3]+" "+tmp[4];
                    }else{
                        status="1";
                    }
                    time=false;
                }
            }
        }

        return sqlList;
    }

}
